import { Injectable, Logger } from '@nestjs/common';
import { v4 as uuidv4 } from 'uuid';
import { CreateMessageDto, MessageResponseDto } from '../dto/messages.dto';
import { AnthropicMessage, AnthropicContentBlock } from '../interfaces/anthropic-api.interface';
import { TokenManagerService } from '../services/token-manager.service';
import { ProxyConfigService } from '../config/proxy.config';
import { CopilotRequestLoggerService } from '../services/copilot-request-logger.service';


// Copilot API 接口定义
export interface CopilotMessage {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

export interface CopilotRequest {
  messages: CopilotMessage[];
  model: string;
  temperature?: number;
  top_p?: number;
  n?: number;
  max_tokens?: number;
  stream?: boolean;
  tools?: any[];
  tool_choice?: any;
  intent?: boolean;
  intent_threshold?: number;
  intent_content?: string;
}

export interface CopilotChoice {
  index: number;
  message: {
    role: 'assistant';
    content: string;
    tool_calls?: any[];
  };
  finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter';
}

export interface CopilotResponse {
  id: string;
  object: 'chat.completion' | 'chat.completion.chunk';
  created: number;
  model: string;
  choices: CopilotChoice[];
  usage?: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
}

@Injectable()
export class CopilotAdapter {
  private readonly logger = new Logger(CopilotAdapter.name);

  constructor(
    private readonly tokenManager: TokenManagerService,
    private readonly configService: ProxyConfigService,
    private readonly copilotLogger: CopilotRequestLoggerService
  ) {}

  /**
   * 初始化GitHub token（用于获取Copilot token）
   */
  initializeGithubToken(githubToken: string): void {
    this.tokenManager.setGithubToken(githubToken);
    this.logger.log('GitHub token initialized for Copilot token management');
  }

  /**
   * 将 Anthropic 格式的请求转换为 Copilot 格式
   */
  async convertAnthropicToCopilot(anthropicRequest: CreateMessageDto, requestId?: string): Promise<CopilotRequest> {
    const conversionStartTime = Date.now();
    
    // 记录转换开始
    if (requestId) {
      await this.copilotLogger.logConversionStart(
        requestId,
        'CopilotAdapter',
        'Anthropic',
        'Copilot',
        {
          originalModel: anthropicRequest.model,
          messageCount: anthropicRequest.messages.length,
          hasSystem: !!anthropicRequest.system,
          hasTools: !!anthropicRequest.tools?.length,
          hasThinking: !!anthropicRequest.thinking?.enabled,
          maxTokens: anthropicRequest.max_tokens,
          temperature: anthropicRequest.temperature
        }
      );
    }
    
    const copilotConfig = await this.configService.getCopilotConfig();
    const copilotRequest: CopilotRequest = {
      messages: this.convertMessages(anthropicRequest.messages, anthropicRequest.system, requestId),
      model: copilotConfig.defaultModel,
      temperature: anthropicRequest.temperature || 0,
      top_p: anthropicRequest.top_p || 1,
      n: 1,
      max_tokens: anthropicRequest.max_tokens,
      stream: false
    };

    // 处理工具调用
    if (anthropicRequest.tools && anthropicRequest.tools.length > 0) {
      copilotRequest.tools = this.convertTools(anthropicRequest.tools);
      copilotRequest.tool_choice = this.convertToolChoice(anthropicRequest.tool_choice);
      
      // 记录工具转换信息
      if (requestId) {
        await this.copilotLogger.logCopilotRequestLegacyFormat({
          requestId,
          phase: 'conversion_start',
          service: 'CopilotAdapter',
          level: 'debug',
          message: 'Converting tools from Anthropic to Copilot format',
          data: {
            originalTools: anthropicRequest.tools.map(t => ({ name: t.name, description: t.description })),
            convertedToolsCount: copilotRequest.tools.length,
            toolChoice: anthropicRequest.tool_choice
          }
        });
      }
    }

    // 处理思考模式
    if (anthropicRequest.thinking?.enabled) {
      // Copilot 不直接支持思考模式，可以通过系统提示间接实现
      const systemMessage = copilotRequest.messages.find(m => m.role === 'system');
      if (systemMessage) {
        systemMessage.content += '\n\nPlease think step by step before responding.';
        
        // 记录思考模式处理
        if (requestId) {
          await this.copilotLogger.logCopilotRequestLegacyFormat({
            requestId,
            phase: 'conversion_start',
            service: 'CopilotAdapter',
            level: 'debug',
            message: 'Applied thinking mode via system message modification',
            data: { thinkingEnabled: true }
          });
        }
      }
    }

    const conversionDuration = Date.now() - conversionStartTime;
    
    // 简化的控制台日志
    this.logger.debug(`Anthropic->Copilot conversion completed (${conversionDuration}ms)`);
    
    // 记录转换完成
    if (requestId) {
      await this.copilotLogger.logConversionComplete(
        requestId,
        'CopilotAdapter',
        'Anthropic',
        'Copilot',
        {
          convertedRequest: {
            model: copilotRequest.model,
            messageCount: copilotRequest.messages.length,
            hasTools: !!copilotRequest.tools?.length,
            temperature: copilotRequest.temperature,
            maxTokens: copilotRequest.max_tokens
          },
          fieldMappings: {
            'model': `${anthropicRequest.model} -> ${copilotRequest.model}`,
            'messages': `${anthropicRequest.messages.length} -> ${copilotRequest.messages.length}`,
            'tools': `${anthropicRequest.tools?.length || 0} -> ${copilotRequest.tools?.length || 0}`
          }
        },
        conversionDuration
      );
    }

    return copilotRequest;
  }

  /**
   * 将 Copilot 格式的响应转换为 Anthropic 格式
   */
  convertCopilotToAnthropic(copilotResponse: CopilotResponse, originalRequest: CreateMessageDto, requestId?: string): MessageResponseDto {
    const conversionStartTime = Date.now();
    
    if (!copilotResponse.choices || copilotResponse.choices.length === 0) {
      const error = new Error('No choices in Copilot response');
      if (requestId) {
        this.copilotLogger.logErrorLegacy(
          requestId,
          'CopilotAdapter',
          'No choices in Copilot response',
          error,
          { copilotResponse }
        );
      }
      throw error;
    }
    
    const choice = copilotResponse.choices[0];
    if (!choice) {
      const error = new Error('First choice is null in Copilot response');
      if (requestId) {
        this.copilotLogger.logErrorLegacy(
          requestId,
          'CopilotAdapter',
          'First choice is null in Copilot response',
          error,
          { copilotResponse }
        );
      }
      throw error;
    }

    // 记录响应转换开始
    if (requestId) {
      this.copilotLogger.logCopilotRequestLegacyFormat({
        requestId,
        phase: 'response_conversion',
        service: 'CopilotAdapter',
        level: 'debug',
        message: 'Starting Copilot to Anthropic response conversion',
        data: {
          copilotResponse: {
            id: copilotResponse.id,
            model: copilotResponse.model,
            choicesCount: copilotResponse.choices.length,
            finishReason: choice.finish_reason,
            hasContent: !!choice.message.content,
            hasToolCalls: !!choice.message.tool_calls?.length,
            usage: copilotResponse.usage
          }
        }
      });
    }

    const content: AnthropicContentBlock[] = [];

    // 处理普通文本内容
    if (choice.message.content) {
      content.push({
        type: 'text',
        text: choice.message.content
      });
    }

    // 处理工具调用
    if (choice.message.tool_calls) {
      choice.message.tool_calls.forEach(toolCall => {
        content.push({
          type: 'tool_use',
          name: toolCall.function.name,
          input: JSON.parse(toolCall.function.arguments),
          tool_use_id: toolCall.id
        });
      });
      
      // 记录工具调用转换
      if (requestId) {
        this.copilotLogger.logCopilotRequestLegacyFormat({
          requestId,
          phase: 'response_conversion',
          service: 'CopilotAdapter',
          level: 'debug',
          message: 'Converting tool calls from Copilot to Anthropic format',
          data: {
            toolCallsCount: choice.message.tool_calls.length,
            toolCalls: choice.message.tool_calls.map(tc => ({
              id: tc.id,
              name: tc.function.name,
              argumentsLength: tc.function.arguments.length
            }))
          }
        });
      }
    }

    const anthropicResponse: MessageResponseDto = {
      id: copilotResponse.id || this.generateAnthropicMessageId(),
      type: 'message',
      role: 'assistant',
      content,
      model: originalRequest.model, // 使用原始请求的模型名而不是copilot返回的
      stop_reason: this.mapFinishReason(choice.finish_reason),
      stop_sequence: null,
      usage: {
        input_tokens: copilotResponse.usage?.prompt_tokens || 0,
        cache_creation_input_tokens: 0,
        cache_read_input_tokens: 0,
        output_tokens: copilotResponse.usage?.completion_tokens || 0,
        service_tier: 'standard'
      }
    };

    const conversionDuration = Date.now() - conversionStartTime;
    
    // 简化的控制台日志
    this.logger.debug(`Copilot->Anthropic conversion completed (${conversionDuration}ms)`);
    
    // 记录转换完成
    if (requestId) {
      this.copilotLogger.logResponseConversion(
        requestId,
        'CopilotAdapter',
        'Converted Copilot response to Anthropic format',
        {
          anthropicResponse: {
            id: anthropicResponse.id,
            model: anthropicResponse.model,
            contentBlocksCount: anthropicResponse.content.length,
            stopReason: anthropicResponse.stop_reason,
            usage: anthropicResponse.usage
          },
          conversionDetails: {
            textBlocks: content.filter(c => c.type === 'text').length,
            toolUseBlocks: content.filter(c => c.type === 'tool_use').length,
            finishReasonMapping: `${choice.finish_reason} -> ${anthropicResponse.stop_reason}`
          }
        },
        conversionDuration
      );
    }

    return anthropicResponse;
  }

  /**
   * 转换消息格式
   */
  private convertMessages(anthropicMessages: any[], systemPrompt?: string | AnthropicContentBlock[], requestId?: string): CopilotMessage[] {
    const copilotMessages: CopilotMessage[] = [];

    // 添加系统提示
    if (systemPrompt) {
      let systemContent = '';
      if (typeof systemPrompt === 'string') {
        systemContent = systemPrompt;
      } else if (Array.isArray(systemPrompt)) {
        systemContent = systemPrompt
          .filter(block => block.type === 'text')
          .map(block => block.text)
          .join('\n');
      }

      if (systemContent) {
        copilotMessages.push({
          role: 'system',
          content: systemContent
        });
        
        // 记录系统消息转换
        if (requestId) {
          this.copilotLogger.logCopilotRequestLegacyFormat({
            requestId,
            phase: 'conversion_start',
            service: 'CopilotAdapter',
            level: 'debug',
            message: 'Converted system prompt',
            data: {
              systemPromptType: typeof systemPrompt,
              systemContentLength: systemContent.length,
              isArray: Array.isArray(systemPrompt)
            }
          });
        }
      }
    }

    // 转换用户和助手消息
    anthropicMessages.forEach((message, index) => {
      let messageContent = '';
      let contentBlocks = { text: 0, toolResult: 0, other: 0 };
      
      if (!message.content) {
        if (requestId) {
          this.copilotLogger.logCopilotRequestLegacyFormat({
            requestId,
            phase: 'conversion_start',
            service: 'CopilotAdapter',
            level: 'warn',
            message: `Skipping message ${index} - no content`,
            data: { messageIndex: index, role: message.role }
          });
        }
        return; // 跳过没有内容的消息
      }
      
      if (typeof message.content === 'string') {
        messageContent = message.content;
        contentBlocks.text = 1;
      } else if (Array.isArray(message.content)) {
        // 提取文本内容，忽略其他类型的内容块
        const textBlocks = message.content.filter(block => block && block.type === 'text');
        messageContent = textBlocks.map(block => block.text || '').join('\n');
        contentBlocks.text = textBlocks.length;
          
        // 处理工具结果
        const toolResults = message.content.filter(block => block && block.type === 'tool_result');
        if (toolResults.length > 0) {
          const toolResultText = toolResults
            .map(result => `Tool result: ${result.content || ''}`)
            .join('\n');
          messageContent += '\n' + toolResultText;
          contentBlocks.toolResult = toolResults.length;
        }
        
        contentBlocks.other = message.content.length - contentBlocks.text - contentBlocks.toolResult;
      }

      if (messageContent) {
        copilotMessages.push({
          role: message.role === 'user' ? 'user' : 'assistant',
          content: messageContent
        });
        
        // 记录消息转换详情
        if (requestId) {
          this.copilotLogger.logCopilotRequestLegacyFormat({
            requestId,
            phase: 'conversion_start',
            service: 'CopilotAdapter',
            level: 'debug',
            message: `Converted message ${index}`,
            data: {
              messageIndex: index,
              role: message.role,
              contentType: typeof message.content,
              contentBlocks,
              finalContentLength: messageContent.length
            }
          });
        }
      }
    });

    // 记录消息转换结果
    if (requestId) {
      this.copilotLogger.logCopilotRequestLegacyFormat({
        requestId,
        phase: 'conversion_complete',
        service: 'CopilotAdapter',
        level: 'debug',
        message: 'Message conversion completed',
        data: {
          originalMessageCount: anthropicMessages.length,
          convertedMessageCount: copilotMessages.length,
          hasSystemMessage: !!systemPrompt,
          messageRoles: copilotMessages.map(m => m.role)
        }
      });
    }
    
    return copilotMessages;
  }

  /**
   * 转换工具定义
   */
  private convertTools(anthropicTools: any[]): any[] {
    return anthropicTools.map(tool => ({
      type: 'function',
      function: {
        name: tool.name,
        description: tool.description,
        parameters: tool.input_schema
      }
    }));
  }

  /**
   * 转换工具选择策略
   */
  private convertToolChoice(anthropicToolChoice?: any): any {
    if (!anthropicToolChoice) {
      return 'auto';
    }

    switch (anthropicToolChoice.type) {
      case 'auto':
        return 'auto';
      case 'any':
        return 'required';
      case 'tool':
        return {
          type: 'function',
          function: { name: anthropicToolChoice.name }
        };
      case 'none':
        return 'none';
      default:
        return 'auto';
    }
  }


  /**
   * 映射完成原因
   */
  private mapFinishReason(copilotFinishReason: string): 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | 'pause_turn' | 'refusal' {
    switch (copilotFinishReason) {
      case 'stop':
        return 'end_turn';
      case 'length':
        return 'max_tokens';
      case 'tool_calls':
        return 'tool_use';
      case 'content_filter':
        return 'refusal';
      default:
        return 'end_turn';
    }
  }

  /**
   * 生成Anthropic格式的消息ID
   */
  private generateAnthropicMessageId(): string {
    // 生成类似 msg_01YNP7b9mhAzQMRkjwEnGVHF 的格式
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = 'msg_';
    for (let i = 0; i < 24; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }

  /**
   * 生成请求头部
   */
  async generateRequestHeaders(copilotConfig: any): Promise<Record<string, string>> {
    const requestId = uuidv4();
    const interactionId = uuidv4();

    // 获取有效的Copilot token
    const validToken = await this.tokenManager.getValidToken();

    const headers = {
      ...copilotConfig.headers,
      'authorization': `Bearer ${validToken}`,
      'user-agent': copilotConfig.userAgent || 'GithubCopilot/1.348.0',
      'x-request-id': requestId,
      'x-interaction-id': interactionId,
    };

    // 不要手动设置 content-length，让 axios 自动计算
    return headers;
  }
}